﻿#include "pch.h"
#include "SvnOpPage.xaml.h"
#if __has_include("SvnOpPage.g.cpp")
#include "SvnOpPage.g.cpp"
#endif

#include <winrt/Windows.ApplicationModel.DataTransfer.h>
#include "../src/ViewHelpers.h"

using namespace winrt;
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::UI::Xaml::Controls;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.




namespace winrt::GMTK::implementation
{

    int32_t SvnOpPage::MyProperty()
    {
        throw hresult_not_implemented();
    }

    void SvnOpPage::MyProperty(int32_t /* value */)
    {
        throw hresult_not_implemented();
    }


    void SvnOpPage::InitComboBox()
    {
        ::GMTK::Helpers::PopulateComboBoxFromMapStringKeys(ComboBox_Project(), projPathMap, Utility::lastSVNTarget);
        ::GMTK::Helpers::PopulateComboBoxFromMapStringKeys(ComboBox_Suffix(), suffixMap, Utility::lastSVNSuffix);
        ::GMTK::Helpers::PopulateComboBoxFromMapStringKeys(ComboBox_Merge_Suffix(), suffixMap, Utility::lastMergeSuffix);
        ::GMTK::Helpers::PopulateComboBoxFromMapStringKeys(ComboBox_Merge_Source(), projPathMap, Utility::lastMergeSource);
        ::GMTK::Helpers::PopulateComboBoxFromMapStringKeys(ComboBox_Merge_Target(), projPathMap, Utility::lastMergeTarget);
    }

    void SvnOpPage::AutoSetMergeTarget()
    {
        // 如果是合并模式，自动设置目标目录
        if (currentMergePurpose == EMergePurpose::Merge)
        {
            if (ComboBox_Merge_Source().SelectedItem() != nullptr)
            {
                auto sourceItem = ComboBox_Merge_Source().SelectedItem().as<ComboBoxItem>();
                if (sourceItem != nullptr)
                {
                    auto sourceName = unbox_value<hstring>(sourceItem.Content());
                    std::string sourceNameStr = to_string(sourceName);
                    
                    // 如果源目录名称已经包含DEV，则跳过自动设置
                    if (sourceNameStr.find("_DEV") != std::string::npos)
                    {
                        return;
                    }
                    
                    std::string targetNameStr = sourceNameStr + "_DEV";
                    
                    // 在目标目录ComboBox中查找对应的项目
                    for (uint32_t i = 0; i < ComboBox_Merge_Target().Items().Size(); ++i)
                    {
                        auto item = ComboBox_Merge_Target().Items().GetAt(i).as<ComboBoxItem>();
                        if (item != nullptr)
                        {
                            auto itemName = unbox_value<hstring>(item.Content());
                            if (to_string(itemName) == targetNameStr)
                            {
                                ComboBox_Merge_Target().SelectedIndex(i);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    void SvnOpPage::OnLoaded(IInspectable const&, RoutedEventArgs const& )
    {
        LOG_DEBUG(L"On Load:" + GetRuntimeClassName());
		InitComboBox();
        RadioMerge().IsChecked(true);

        Utility::SetUiErrorHandler([this](const winrt::hstring& msg)
            {
                this->DispatcherQueue().TryEnqueue([this, msg]()
                    {
                        ContentDialog dialog;
                        dialog.Title(box_value(L"错误"));
                        TextBlock textBlock;
                        textBlock.Text(msg);
                        dialog.Content(textBlock);
                        dialog.CloseButtonText(L"确定");
                        dialog.XamlRoot(this->XamlRoot());
                        dialog.ShowAsync();
                    });
            });
    }


#pragma region Event 
    static std::string GetSvnTargetPath()
    {
        std::string path = Utility::GetProjPathMap().at(Utility::lastSVNTarget);
        std::string& suffix = Utility::GetSuffixMap().at(Utility::lastSVNSuffix);
        path += "\\" + suffix;

        return path;
    }

    static std::string GetMergeTargetPath()
    {
		std::string path = Utility::GetProjPathMap().at(Utility::lastMergeTarget);
		std::string& suffix = Utility::GetSuffixMap().at(Utility::lastMergeSuffix);
		path += "\\" + suffix;

		return path;
    }

    static std::string GetMergeSourcePath()
    {
        std::string path = Utility::GetProjPathMap().at(Utility::lastMergeSource);
        std::string& suffix = Utility::GetSuffixMap().at(Utility::lastMergeSuffix);
        path += "\\" + suffix;

        return path;
    }

    std::string GetMergeSourceUrl()
	{
		std::string sourceRootUrl = Utility::GetUrlMap().at(Utility::lastMergeSource);
		std::string& suffix = Utility::GetSuffixMap().at(Utility::lastMergeSuffix);

		return sourceRootUrl + "\\" + suffix;
	}

    void SvnOpPage::Update_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
        Utility::RunVcsUpdate(GetSvnTargetPath());
    }

    void SvnOpPage::Commit_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
        Utility::RunVcsCommit(GetSvnTargetPath());
    }

    void SvnOpPage::Log_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
		Utility::RunVcsLog(GetSvnTargetPath());
    }

    void SvnOpPage::Revert_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
        Utility::RunVcsRevert(GetSvnTargetPath());
    }

    void SvnOpPage::CleanUp_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
		Utility::RunVcsCleanup(GetSvnTargetPath());
    }

    void SvnOpPage::Open_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
		Utility::OpenFolder(GetSvnTargetPath());
    }

    void SvnOpPage::M_Update_Click(Windows::Foundation::IInspectable const& /*sender*/, Microsoft::UI::Xaml::RoutedEventArgs const& /*args*/)
    {
		Utility::RunVcsUpdate(GetMergeTargetPath());
    }

    void SvnOpPage::M_Commit_Click(Windows::Foundation::IInspectable const& /*sender*/, Microsoft::UI::Xaml::RoutedEventArgs const& /*args*/)
    {
		Utility::RunVcsCommit(GetMergeTargetPath());
    }

    void SvnOpPage::M_Log_Click(Windows::Foundation::IInspectable const& /*sender*/, Microsoft::UI::Xaml::RoutedEventArgs const& /*args*/)
    {
		Utility::RunVcsLog(GetMergeTargetPath());

    }

    void SvnOpPage::M_Revert_Click(Windows::Foundation::IInspectable const& /*sender*/, Microsoft::UI::Xaml::RoutedEventArgs const& /*args*/)
    {
		Utility::RunVcsRevert(GetMergeTargetPath());
    }

    void SvnOpPage::M_CleanUp_Click(Windows::Foundation::IInspectable const& /*sender*/, Microsoft::UI::Xaml::RoutedEventArgs const& /*args*/)
    {
		Utility::RunVcsCleanup(GetMergeTargetPath());
    }

    void SvnOpPage::Merge_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args*/)
    {
        if (Utility::lastMergeSource == Utility::lastMergeTarget)
        {
            ContentDialog errorDialog;

            errorDialog.Title(box_value(L"错误"));

            // 使用 TextBlock 包装错误信息
            TextBlock textBlock;
            textBlock.Text(L"相同项目不能合并");
            errorDialog.Content(textBlock);
            errorDialog.CloseButtonText(L"确定");

            errorDialog.XamlRoot(this->XamlRoot());
            // 显示对话框
            errorDialog.ShowAsync();
			return;
        }

		auto sourceUrl = GetMergeSourceUrl();
		auto targetPath = GetMergeTargetPath();
        LOG_INFO(L"Merge: " + winrt::to_hstring(sourceUrl) + L" -> " + winrt::to_hstring(targetPath));

		Utility::RunVcsMerge(sourceUrl, targetPath);
    }

    void SvnOpPage::Compare_Click(Windows::Foundation::IInspectable const& /*sender*/, Microsoft::UI::Xaml::RoutedEventArgs const& /*args*/)
    {
        const std::string sourcePath = GetMergeSourcePath();
        const std::string targetPath = GetMergeTargetPath();
        // 带引号以兼容路径中的空格
        const std::string command = std::string("\"") + Utility::comparePath + "\" \"" + sourcePath + "\" \"" + targetPath + "\"";
        LOG_INFO(L"Compare: " + winrt::to_hstring(sourcePath) + L" -> " + winrt::to_hstring(targetPath));

        Utility::StartProcessAsync(command);
    }

    void SvnOpPage::ComboBox_Project_SelectionChanged(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Microsoft::UI::Xaml::Controls::SelectionChangedEventArgs const& /*args*/)
    {
		auto item = ComboBox_Project().SelectedItem().as<ComboBoxItem>();
        if (item != nullptr)
        {
			auto name = unbox_value<hstring>(item.Content());
            Utility::SetLastSVNTarget(to_string(name));
        }
    }


    void SvnOpPage::ComboBox_Suffix_SelectionChanged(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Microsoft::UI::Xaml::Controls::SelectionChangedEventArgs const& /*args*/)
    {
		auto item = ComboBox_Suffix().SelectedItem().as<ComboBoxItem>();
        if (item != nullptr)
        {
            auto name = unbox_value<hstring>(item.Content());
            Utility::SetLastSVNSuffix(to_string(name));
        }
    }
    void SvnOpPage::Open_Merge_Source_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args */)
    {
		Utility::OpenFolder(GetMergeSourcePath());
    }
    void SvnOpPage::Open_Merge_Target_Click(Windows::Foundation::IInspectable const& /* sender */, Microsoft::UI::Xaml::RoutedEventArgs const& /* args */)
    {
		Utility::OpenFolder(GetMergeTargetPath());
    }
    void SvnOpPage::ComboBox_Merge_Suffix_SelectionChanged(winrt::Windows::Foundation::IInspectable const& /* sender */, winrt::Microsoft::UI::Xaml::Controls::SelectionChangedEventArgs const& /* args */)
    {
		auto item = ComboBox_Merge_Suffix().SelectedItem().as<ComboBoxItem>();
		if (item != nullptr)
		{
			auto name = unbox_value<hstring>(item.Content());
			Utility::SetLastMergeSuffix(to_string(name));
		}
    }
    void SvnOpPage::ComboBox_Merge_Source_SelectionChanged(winrt::Windows::Foundation::IInspectable const& /* sender */, winrt::Microsoft::UI::Xaml::Controls::SelectionChangedEventArgs const& /* args */)
    {
		auto item = ComboBox_Merge_Source().SelectedItem().as<ComboBoxItem>();
        if (item != nullptr)
        {
            auto name = unbox_value<hstring>(item.Content());
            Utility::SetLastMergeSource(to_string(name));
            
            // 调用自动设置目标目录函数
            AutoSetMergeTarget();
        }
    }
    void SvnOpPage::ComboBox_Merge_Target_SelectionChanged(winrt::Windows::Foundation::IInspectable const& /* sender */, winrt::Microsoft::UI::Xaml::Controls::SelectionChangedEventArgs const& /* args */)
    {
		auto item = ComboBox_Merge_Target().SelectedItem().as<ComboBoxItem>();
		if (item != nullptr)
		{
			auto name = unbox_value<hstring>(item.Content());
			Utility::SetLastMergeTarget(to_string(name));
		}
    }

    void SvnOpPage::GetLog_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*args*/)
    {
        SetLogBusy(true);

        auto enqueueCopyLogDialog = [&,this](winrt::hstring htextToCopy)
            {
				this->DispatcherQueue().TryEnqueue([this,htextToCopy]()
                    {
                        SetLogBusy(false);
                        if (!htextToCopy.empty())
                        {
                            // 创建 DataPackage 对象
                            winrt::Windows::ApplicationModel::DataTransfer::DataPackage dataPackage;
                            dataPackage.SetText(htextToCopy);

                            // 将 DataPackage 设置到剪贴板
                            winrt::Windows::ApplicationModel::DataTransfer::Clipboard::SetContent(dataPackage);
                        }

                        ContentDialog dialog;
                        dialog.Title(box_value(L"提示"));

                        // 使用 TextBlock 包装错误信息
                        TextBlock textBlock;
                        textBlock.Text(htextToCopy.empty() ? L"又摸了一天鱼" : L"今日日志已复制");
                        dialog.Content(textBlock);
                        dialog.CloseButtonText(L"确定");

                        dialog.XamlRoot(this->XamlRoot());
                        // 显示对话框
                        dialog.ShowAsync();
                    });

			};

        Utility::CopySvnLog(Utility::svnAuthor, enqueueCopyLogDialog);
    }

    void SvnOpPage::SetLogBusy(bool busy)
    {
        BtnGetLog().IsEnabled(!busy);
        LogProgress().IsActive(busy);
        LogProgress().Visibility(busy ? Visibility::Visible : Visibility::Collapsed);
    }


    void SvnOpPage::RadioMerge_Checked(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& /*e*/)
    {
        currentMergePurpose = EMergePurpose::Merge;
        
        // 调用自动设置目标目录函数
        AutoSetMergeTarget();
    }

    void SvnOpPage::RadioTransplant_Checked(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& /*e*/)
    {
        currentMergePurpose = EMergePurpose::Transplant;
        // 移植模式不需要自动选择目标目录，用户手动选择
    }

#pragma endregion
}

